package com.household.security.config;

import com.household.constant.SecurityConstant;
import com.household.security.filter.MyLoginFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Created By wanzhen
 * 2023. 2023/3/25. 13:46
 */

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true,jsr250Enabled = true)
public class MySecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    private final MyUserDetailsService myUserDetailsService;

    @Autowired
    public MySecurityConfigurerAdapter(MyUserDetailsService myUserDetailsService) {
        this.myUserDetailsService = myUserDetailsService;
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public MyLoginFilter myLoginFilter() throws Exception {
        MyLoginFilter myLoginFilter = new MyLoginFilter();
        myLoginFilter.setFilterProcessesUrl(SecurityConstant.FILTER_PROCESSES_URL);
        myLoginFilter.setKaptchaParameter(SecurityConstant.VERIFTYCODE);
        myLoginFilter.setUsernameParameter(SecurityConstant.USERNAME);
        myLoginFilter.setPasswordParameter(SecurityConstant.PASSWORD);
        myLoginFilter.setAuthenticationManager(authenticationManagerBean());
        myLoginFilter.setAuthenticationSuccessHandler(((request, response, authentication) -> {
            response.sendRedirect(SecurityConstant.LOGIN_TO_URL);

        }));
        myLoginFilter.setAuthenticationFailureHandler(((request, response, exception) -> {
            request.getSession().setAttribute(SecurityConstant.LAST_EXCEPTION,exception);
            response.sendRedirect(SecurityConstant.UN_AUTHENTICATION_URL);
        }));
        return myLoginFilter;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .mvcMatchers(SecurityConstant.UN_AUTHENTICATION_URL).permitAll()
                .mvcMatchers("/auth/register").permitAll()
                .mvcMatchers("/register").permitAll()
                .mvcMatchers("/login.html").permitAll()
                .mvcMatchers("/vg.jpg").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage(SecurityConstant.UN_AUTHENTICATION_URL)
                .and()
                .logout()
                .logoutUrl("/logout")
                .and()
                .rememberMe()
                .and()
                .csrf().disable();
        http.addFilterAt(myLoginFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 设置拦截忽略文件夹，可以对静态资源放行
        web.ignoring().mvcMatchers("/assets/**");
    }
}
